
using System;
using System.Threading;

using Microsoft.SPOT;
using Microsoft.SPOT.Input;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Media;

using Microsoft.NETMF.BikeComputer.Hardware;


namespace Microsoft.NETMF.BikeComputer.Application
{
    public class ComputerController
    {

        private enum states { NotStarted, Riding, Paused, Done };

        //--//

        public ComputerController(Program application, RideDataModel model)
        {
            _application = application;
            _model = model;

            Microsoft.SPOT.Touch.Touch.Initialize(_application);

            _currentState = states.NotStarted;
            _elapsedTime = new ElapsedTimer();

            if (Microsoft.SPOT.Hardware.SystemInfo.SystemID.SKU == 3)   //we are running on the emulator
            {
                _inclineSensor = new FakeInclineSensor();
                _speedSensor = new FakeSwitchSensor(12);
                _cadenceSensor = new FakeSwitchSensor(1);
            }

            else
            {
                _inclineSensor = new InclineSensor(this);
                _speedSensor = new SwitchSensor(GHIElectronics.NETMF.Hardware.EMX.Pin.IO18);
                _cadenceSensor = new SwitchSensor(GHIElectronics.NETMF.Hardware.EMX.Pin.IO19);
            }

        }

        public void AttachView( ReadyView readyView, SettingsView settingsView, RideView rideView, DataView dataView, SummaryView summaryView,ZeroInclinometerView zeroInclinometer, Window mainWindow)
        {
            _readyView = readyView;
            _settingsView = settingsView;
            _rideView = rideView;
            _dataView = dataView;
            _summaryView = summaryView;
            _zeroInclinometer = zeroInclinometer;
            _mainWindow = mainWindow;
        }

        public void Start(View initialView)
        {
            ChangeView(_readyView);
            _mainWindow.TouchGestureChanged += new TouchGestureEventHandler(ComputerController_TouchGestureChanged);
        }



        public void Shutdown()
        {
        //save data?   Displose of anything?
        }



 //       public TouchEventHandler _zeroInclinometer_TouchUp(object sender, TouchEventArgs e)
        public void _zeroInclinometer_Click(object sender, EventArgs e)
        {
            ChangeView(_zeroInclinometer); 
        }


        void ComputerController_TouchGestureChanged(object sender, TouchGestureEventArgs e)  // this handles the gestures for the non-ride state
        {
            TouchGesture currentGesture = e.Gesture;
            switch (_currentState)
            {
                case states.NotStarted:     // in the NOtStarted state, the only gesture that we respond to is the UP/start gesture
                    {
                        switch (currentGesture)
                        {
                            case TouchGesture.Up:
                                {
                                    _currentState = states.Riding;
                                    ((IPausable)_speedSensor).Resume();
                                    ((IPausable)_cadenceSensor).Resume();
                                    ((IPausable)_inclineSensor).Resume();
                                    _elapsedTime.StartElapsedTimer();
                                    ChangeView(_rideView);
                                    //temporary timer control - this will move to the ADIS16203 if we can figure that out
                                    _UpdateTimer = new Timer(new TimerCallback(UpdateTimerEventHandler), null, 10000, 10000);
                                    break;
                                }
                            case TouchGesture.Left:  //we only have the Ride and Summary views while in the ride state
                                {
                                    if (_mainWindow.Child == _readyView)
                                        ChangeView(_settingsView);
                                    else if (_mainWindow.Child == _settingsView)
                                        ChangeView(_dataView);
                                    else
                                        ChangeView(_readyView);
                                    break;
                                }
                            case TouchGesture.Right:  //we only have two views to switch between 
                                {
                                    if (_mainWindow.Child == _readyView)
                                        ChangeView(_dataView);
                                    else if (_mainWindow.Child == _dataView)
                                        ChangeView(_settingsView);
                                    else
                                        ChangeView(_readyView);
                                    break;
                                }

                        }

                        break;
                    }


                case states.Riding:     // in the riding state, we need to respond to Left and Right to change the view and down to pause the Ride
                    {
                        switch (currentGesture)
                        {
                            case TouchGesture.Down:
                                {
                                    _currentState = states.Paused;
                                    ((IPausable)_speedSensor).Pause();
                                    ((IPausable)_cadenceSensor).Pause();
                                    ((IPausable)_inclineSensor).Pause();
                                    _elapsedTime.StopElapsedTimer();
                                    _rideView.PauseRide();
                                    _summaryView.PauseRide();
                                    _UpdateTimer.Dispose();
                                    break;
                                }
                            case TouchGesture.Left:  //we only have the Ride and Summary views while in the ride state
                                {
                                    if (_mainWindow.Child == _rideView)
                                        ChangeView(_summaryView);
                                    else
                                        ChangeView(_rideView);
                                    break;
                                }
                            case TouchGesture.Right:  //we only have two views to switch between 
                                {
                                    if (_mainWindow.Child == _rideView)
                                        ChangeView(_summaryView);
                                    else
                                        ChangeView(_rideView);
                                    break;
                                }

                        }


                        break;
                    }

                case states.Paused:     // in the paused state, we need to respond to the Left and Right Gestures to change the view and the up to restart and the down to stop the ride
                    {
                        switch (currentGesture)
                        {
                            case TouchGesture.Up:
                                {
                                    _currentState = states.Riding;
                                    ((IPausable)_speedSensor).Resume();
                                    ((IPausable)_cadenceSensor).Resume();
                                    ((IPausable)_inclineSensor).Resume();
                                    _elapsedTime.StartElapsedTimer();
                                    _rideView.ResumeRide();
                                    _summaryView.ResumeRide();
                                    //temporary timer control - this will move to the ADIS16203 if we can figure that out
                                    _UpdateTimer = new Timer(new TimerCallback(UpdateTimerEventHandler), null, 10000, 10000);
                                    break;
                                }
                            case TouchGesture.Down:
                                {
                                    // this is where we need to confirm the end of the ride before changing state
                                    _currentState = states.Done;
                                    ((IPausable)_speedSensor).Pause();
                                    ((IPausable)_cadenceSensor).Pause();
                                    ((IPausable)_inclineSensor).Pause();
                                    _elapsedTime.StopElapsedTimer();
                                    ChangeView(_dataView);
                                    _UpdateTimer.Dispose();

                                    break;
                                }

                            case TouchGesture.Left:  //we only have the Ride and Summary views while in the ride state
                                {
                                    if (_mainWindow.Child == _readyView)
                                        ChangeView(_summaryView);
                                    else
                                        ChangeView(_rideView);
                                    break;
                                }
                            case TouchGesture.Right:  //we only have two views to switch between 
                                {
                                    if (_mainWindow.Child == _readyView)
                                        ChangeView(_summaryView);
                                    else
                                        ChangeView(_rideView);
                                    break;
                                }

                        }


                        break;
                    }

                case states.Done:       // in the done state, we need to respond to the Left and Right Gestures if we support more views in this state.  
                    {


                        break;
                    }


            }
        }



        public String getElapsedTime()
        {
            return _elapsedTime.GetElapsedTimeString();
        }



       public void ChangeView(View view)
        {
            _mainWindow.Child = view;
        }



       public void UpdateIncline(double incline)
       {
           _model.Incline = incline;
       }



        public void UpdateTemperature(double temperature)
        {
            _model.Temperature = temperature;
        }



        private void UpdateTimerEventHandler(object o)
        {
            _model.processData(((IInclineSensor)_inclineSensor).GetIncline(),
                ((IInclineSensor)_inclineSensor).GetTemperature(),
                ((ISwitchSensor)_speedSensor).getSwitchCount(), 
                ((ISwitchSensor)_cadenceSensor).getSwitchCount(), 
                getElapsedTime() );

        }


        //--//

        Program _application;
        Window _mainWindow;
        //--//
        RideDataModel _model;
        //--//
        ReadyView _readyView;
        SettingsView _settingsView;
        RideView _rideView;
        DataView _dataView;
        SummaryView _summaryView;
        public ZeroInclinometerView _zeroInclinometer;
        //--//
        public IInclineSensor _inclineSensor;  
        public  ISwitchSensor _speedSensor;
        public ISwitchSensor _cadenceSensor;
        private ElapsedTimer _elapsedTime;
        //--//
        Timer _UpdateTimer;
        

        //--//
        private states _currentState;
    }
}